/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mycompany.psc.ejb;

import com.mycompany.psc.helpers.DBUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.ScheduleExpression;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.inject.Inject;

/**
 *
 * @author ahmed
 */
@Singleton
@Startup
public class BackupManager {

    @Resource
    TimerService timerService;
    @Inject
    DBUtils dbUtils;
    @Resource(lookup = "PROJECTS_FOLDER")
    private Properties p;
    List<String> fileList = new ArrayList<>();
    String SOURCE_FOLDER = "";
    String OUTPUT_ZIP_FILE = "";

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")
    @PostConstruct
    public void init() {
        ScheduleExpression schedule = new ScheduleExpression();
        System.err.println("started");
        schedule.dayOfWeek("fri");
        

        Timer timer = timerService.createCalendarTimer(schedule);
    }

    @Timeout
    public void backup(Timer timer) {
        performBackup();
    }
    private void performBackup(){
        System.err.println("timed");
        String base = p.getProperty("uri");
        String timestamp=new SimpleDateFormat("yyyyMMddhhmm'.zip'").format(new Date());;
        String output = p.getProperty("backups")+"/"+timestamp;
        dbUtils.backupDB(base + "/psc.sql");
        if (SOURCE_FOLDER.equals("")) {
            SOURCE_FOLDER = base;
        }
        
            OUTPUT_ZIP_FILE = output.trim();
        
        generateFileList(new File(SOURCE_FOLDER));
        zipIt(OUTPUT_ZIP_FILE);
    }

    public void zipIt(String zipFile) {
        
        byte[] buffer = new byte[1024];

        try {

            FileOutputStream fos = new FileOutputStream(zipFile);
            ZipOutputStream zos = new ZipOutputStream(fos);

            System.out.println("Output to Zip : " + zipFile);

            for (String file : this.fileList) {

                System.out.println("File Added : " + file);
                ZipEntry ze = new ZipEntry(file);
                try {
                    zos.putNextEntry(ze);
               

                FileInputStream in
                        = new FileInputStream(SOURCE_FOLDER + File.separator + file);

                int len;
                while ((len = in.read(buffer)) > 0) {
                    zos.write(buffer, 0, len);
                }

                in.close();
                 } catch (java.util.zip.ZipException zipException) {
                    System.err.println("ex="+zipException.getMessage());
                }
            }

            zos.closeEntry();
            //remember close it
            zos.close();

            System.out.println("Done");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private void generateFileList(File node) {

        //add file only
        if (node.isFile()) {
            fileList.add(generateZipEntry(node.getAbsoluteFile().toString()));
        }

        if (node.isDirectory()) {
            String[] subNote = node.list();
            for (String filename : subNote) {
                generateFileList(new File(node, filename));
            }
        }

    }

    /**
     * Format the file path for zip
     *
     * @param file file path
     * @return Formatted file path
     */
    private String generateZipEntry(String file) {
        return file.substring(SOURCE_FOLDER.length() + 1, file.length());
    }
}
